package com.lzx.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzx.common.utils.*;
import com.lzx.user.entity.SysUser;
import com.lzx.user.entity.vo.SearchParams;
import com.lzx.user.mapper.SysUserMapper;
import com.lzx.user.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lzx
 * @since 2022-11-22
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    //后台登录
    @Override
    public R login(SysUser sysUser, HttpServletRequest request) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("mobile", sysUser.getMobile());
        SysUser vo = sysUserMapper.selectOne(wrapper);
        if (vo == null) {
            return R.error().message("手机号不存在");
        }
        //密码匹对
        boolean flag = encoder.matches(sysUser.getPassword(), vo.getPassword());
        if (flag) {
            vo.setIp(IpUtils.getIpAddress(request));
            vo.setAddress(AddressUtils.getCityInfo(IpUtils.getIpAddress(request)));
            sysUserMapper.updateById(vo);
            //redis中存在token
            if (stringRedisTemplate.opsForValue().get("sys:" + sysUser.getMobile() + ":token") != null) {
                return R.ok().data("token", stringRedisTemplate.opsForValue().get("sys:" + sysUser.getMobile() + ":token"));
            }
            //redis中不存在token，则重新生成token
            String token = JwtUtils.getJwtToken(String.valueOf(vo.getId()), vo.getMobile());
            stringRedisTemplate.opsForValue().set("sys:" + sysUser.getMobile() + ":token", token, 1, TimeUnit.HOURS);
            return R.ok().data("token", token);
        } else {
            return R.error().message("密码错误");
        }
    }

    //获取所有用户
    @Override
    public R getSysUserList(int current, int size) {
        List<SysUser> userList = sysUserMapper.getSysUserList();
        //总数量
        int total = userList.size();
        if (size > total) {
            size = total;
        }
        // 求出最大页数，防止currentPage越界
        int maxPage = total % size == 0 ? total / size : total / size + 1;
        if (current > maxPage) {
            current = maxPage;
        }
        // 当前页第一条数据的下标
        int curIdx = current > 1 ? (current - 1) * size : 0;
        List<SysUser> pageList = new ArrayList<>();
        // 将当前页的数据放进pageList
        for (int i = 0; i < size && curIdx + i < total; i++) {
            pageList.add(userList.get(curIdx + i));
        }
        Map<String, Object> map = new HashMap<>();
        map.put("list", pageList);
        map.put("total", total);
        return R.ok().data("map", map);
    }

    //新增用户
    @Override
    public R addSysUser(SysUser sysUser) {
        //通过手机号来查询用户
        SysUser vo = sysUserMapper.selectByMobile(sysUser.getMobile());
        if (vo != null) {
            return R.error().message("手机号已经存在");
        }
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        sysUser.setPassword(encoder.encode(sysUser.getPassword()));
        sysUser.setCreateTime(new Date());
        sysUserMapper.insert(sysUser);
        return R.ok().message("新增成功");
    }

    //修改用户信息
    @Override
    public R updateSysUser(SysUser sysUser) {
        SysUser vo = sysUserMapper.selectById(sysUser.getId());
        sysUser.setUpdateTime(new Date());
        if (!Objects.equals(vo.getMobile(), sysUser.getMobile())) {
            //通过手机号来查询用户
            SysUser sysUser1 = sysUserMapper.selectByMobile(sysUser.getMobile());
            if (sysUser1 != null) {
                return R.error().message("手机号已经存在");
            } else {
                BeanUtils.copyProperties(sysUser, vo);
                sysUserMapper.updateById(vo);
                return R.ok().message("修改成功");
            }
        } else if (!Objects.equals(vo.getPassword(), sysUser.getPassword())) {
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            vo.setPassword(encoder.encode(sysUser.getPassword()));
            sysUserMapper.updateById(vo);
            return R.ok().message("修改成功");
        } else {
            BeanUtils.copyProperties(sysUser, vo);
            sysUserMapper.updateById(vo);
            return R.ok().message("修改成功");
        }
    }

    //禁用用户
    @Override
    public R deleteSysUser(List<Long> ids) {
        sysUserMapper.deleteBatchIds(ids);
        return R.ok().message("禁用成功!");
    }

    //解禁用户
    @Override
    public R relieveSysUser(Long id) {
        SysUser sysUser = sysUserMapper.selectSysUserById(id);
        sysUser.setStatus("0");
        sysUserMapper.updateSysUserById(id);
        return R.ok().message("解禁成功!");
    }

    //根据id获取用户信息
    @Override
    public R getSysUser(Long id) {
        SysUser sysUser = sysUserMapper.selectSysUserById(id);
        return R.ok().data("sysUser", sysUser);
    }

    //搜索
    @Override
    public R searchSysUser(SearchParams searchParams) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        if (StringUtils.isNoneBlank(searchParams.getMobile())) {
            wrapper.like("mobile", searchParams.getMobile());
        }
        if (StringUtils.isNoneBlank(searchParams.getUsername())) {
            wrapper.like("username", searchParams.getUsername());
        }
        List<SysUser> list = sysUserMapper.selectList(wrapper);
        return R.ok().data("list", list);
    }

    //根据token获取个人信息
    @Override
    public R getSysUserInfo(HttpServletRequest request) {
        String s;
        SysUser sysUser;
        //判断请求头中是否携带token
        if (request.getHeader("token") != null) {
            //校验token是否有效
            if (JwtUtils.checkToken(request.getHeader("token"))) {
                //获取用户id
                String id = JwtUtils.getMemberIdByJwtToken(request);
                sysUser = sysUserMapper.selectById(id);
                //token未过期，从redis中获取
                s = stringRedisTemplate.opsForValue().get("sys:" + sysUser.getMobile() + ":token");
            } else {
                return R.error().message("token过期了");
            }
        } else {
            return R.error().message("token不存在!");
        }
        if (s == null) {
            log.info("token过期了");
            return R.error().message("token过期了");
        }
        return R.ok().data("sysUser", sysUser);
    }

    //导出
    @Override
    public void exportSysUser(HttpServletResponse response) {
        List<SysUser> userList = sysUserMapper.selectList(null);
        ExcelUtils.export(response, "系统用户信息", SysUser.class, userList);
    }
}
